from decimal import Decimal

from django.core.paginator import Paginator
from django.shortcuts import render
from django.utils.timezone import now
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView,ListAPIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from django_redis import get_redis_connection
from .models import OrderInfo,OrderGoods
from users.models import User,Address
from goods.models import SKU
from django.db import transaction
from .serializers import OrderListSerializer,OrderSKUSerializer,CommentOrderSerializer
# Create your views here.

class GenerateOrderDetailView(APIView):
    permission_classes = [IsAuthenticated]
    def get(self,request):
        user = request.user
        if user is None:
            return Response({'message':'用户信息错误'},status=status.HTTP_400_BAD_REQUEST)

        redis = get_redis_connection('cart')

        cart_id_count = redis.hgetall('cart_%s'%user.id)
        cart_selected = redis.smembers('cart_selected_%s'%user.id)

        cart_redis={}
        for id in cart_selected:
            cart_redis[int(id)] = int(cart_id_count[id])

        from .serializers import CartGoodsSerializer
        from goods.models import SKU

        cart_skus = SKU.objects.filter(pk__in=cart_redis.keys())
        for sku in cart_skus:
            sku.count = cart_redis[sku.id]

        serializer = CartGoodsSerializer(cart_skus,many=True)

        freight = Decimal(10.00)

        return Response({'freight':freight,'skus':serializer.data})

class SaveOrderView(APIView):
    permission_classes = [IsAuthenticated]
    def post(self,request):
        user = request.user
        address_id = request.data.get('address')
        try:
            user = User.objects.get(pk=user.id)
        except User.DoesNotExist:
            return Response({'message':'用户不存在'},status=status.HTTP_400_BAD_REQUEST)
        try:
            address = Address.objects.get(pk=address_id)
        except Address.DoesNotExist:
            return Response({'message':'地址不存在'},status=status.HTTP_400_BAD_REQUEST)


        if user is not None and user.is_authenticated:
            pay_method = request.data.get('pay_method')
            order_id = now().strftime('%Y%m%d%M%M%S') +'%09d'%user.id

            with transaction.atomic():
                save_point = transaction.savepoint()
                try:
                    order = OrderInfo.objects.create(
                        order_id = order_id,
                        user = user,
                        address = address,
                        total_count = 0,
                        total_amount =Decimal(0),
                        freight = Decimal(10.00),
                        pay_method = pay_method,
                        status = OrderInfo.ORDER_STATUS_ENUM['UNPAID'] if int(pay_method)==OrderInfo.PAY_METHODS_ENUM['ALIPAY']
                        else OrderInfo.ORDER_STATUS_ENUM['UNSEND']
                    )

                    try:
                        redis = get_redis_connection('cart')
                        cart_id_count = redis.hgetall('cart_%s'%user.id)
                        cart_selected = redis.smembers('cart_selected_%s'%user.id)
                    except Exception:
                        transaction.savepoint_rollback(save_point)
                        raise Exception('读取购物车数据出错！')

                    cart_redis={}
                    for id in cart_selected:
                        cart_redis[int(id)] = int(cart_id_count[id])

                    skus = SKU.objects.filter(pk__in=cart_redis.keys())

                    for sku in skus:
                        while True:
                            count = cart_redis[sku.id]
                            if sku.stock < count:
                                transaction.savepoint_rollback(save_point)
                                raise Exception('库存不足')

                            # sku.stock -= count
                            # sku.sales += count
                            # sku.save()
                            origin_stock = sku.stock
                            origin_sales = sku.sales

                            new_stock = origin_stock - count
                            new_sales = origin_sales + count

                            ret = SKU.objects.filter(id=sku.id,stock=origin_stock).update(
                                stock = new_stock,
                                sales = new_sales
                            )
                            if ret==0:
                                continue


                            order.total_count += count
                            order.total_amount += count * sku.price

                            OrderGoods.objects.create(
                                order = order,
                                sku = sku,
                                count = count,
                                price = sku.price
                            )
                            break
                    order.save()
                except Exception:
                    transaction.savepoint_rollback(save_point)
                    raise Exception('下单失败')

                transaction.savepoint_commit(save_point)

                pl = redis.pipeline()
                pl.hdel('cart_%s'%user.id,*cart_selected)
                pl.srem('cart_selected_%s'%user.id,*cart_selected)
                pl.execute()


            return Response({'order_id':order_id})


        else:
            return Response({'message':'用户登录状态错误'},status=status.HTTP_400_BAD_REQUEST)
    def get(self,request):

        page  = request.query_params.get('page')
        page_size = request.query_params.get('page_size')

        try:
            user = request.user
        except Exception:
            raise Exception('用户状态异常，请重新登录！')

        if user is not None and user.is_authenticated:
            #1.根据用户获取该用户的订单号
            orders_set = OrderInfo.objects.filter(user_id = user.id).order_by('-create_time')

            # serializer = OrderListSerializer(orders_set, many=True)  # 序列化器做序列化处理

            # if not orders_set:
            #     return Response(status=status.HTTP_400_BAD_REQUEST)

            count = orders_set.count()  # 计算订单总量
            Page_set = Paginator(orders_set, page_size)  # 获取分页集合
            cur_page_obj = Page_set.page(int(page)).object_list  # 获取当前页数据对象
            serializer = OrderListSerializer(cur_page_obj, many=True)  # 序列化器做序列化处理


            data = {
                'count':count,
                'results':serializer.data
            }
            return Response(data=data)


class UnCommentOrdersView(APIView):
    permission_classes = [IsAuthenticated]
    def get(self,request,order_id):
        queryset_ordergoods = OrderGoods.objects.filter(order=order_id,is_commented=0)
        sku_list = []
        for sku in queryset_ordergoods:
            sku_list.append(sku.sku.id)
        queryset = SKU.objects.filter(id__in=sku_list)
        serializer = OrderSKUSerializer(queryset,many=True)
        return Response(data=serializer.data)

class CommentOrderView(APIView):
    permission_classes = [IsAuthenticated]
    def post(self,request,order_id):
        orderId = request.data.get('order')
        skuId = request.data.get('sku')
        if order_id!=orderId:
            return Response({'message':'请求数据出错'},status=status.HTTP_400_BAD_REQUEST)
        Obj_OrderGoods = OrderGoods.objects.filter(order=orderId,sku=skuId)
        serializer = CommentOrderSerializer(Obj_OrderGoods,data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)